package org.me.utils;

import java.util.HashMap;

import org.jivesoftware.smack.Connection;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.Roster.SubscriptionMode;
import org.jivesoftware.smack.filter.OrFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Message.Type;
import org.jivesoftware.smack.packet.Presence.Mode;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.muc.InvitationListener;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.packet.MUCUser;
import org.jivesoftware.smackx.provider.MUCUserProvider;
import org.me.Chat;
import org.me.Client;
import org.me.R;
import org.me.RequestMUC;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.widget.LinearLayout;

public class MyService extends Service {
	
	XMPPConnection connection = Koneksi.getInstance().getConnection();
	Roster roster = Koneksi.getInstance().getConnection().getRoster();
	NotificationManager notificationManager;
	PacketListener presenceListener;
	InvitationListener invitationListener;
	boolean errorMUC = false;
	
//	private InvitationListener invitationListener = new InvitationListener() {
//		
//		@Override
//		public void invitationReceived(XMPPConnection conn, final String room, 
//				final String inviter, String reason, final String password, Message message) {
//			// TODO Auto-generated method stub
//			System.out.println("conn= "+conn+" ||room= "+room+" ||inviter= "+inviter+" || reason= "+reason+" ||password= "+password+" ||message= "+message);
//			
//			System.out.println("*****runn********");
//			System.out.println("message= "+message.toXML());
//			
//			org.me.MultiUserChat.room.add(room);
//			
//        	Notif notifgroup = mucnotif.get(inviter);
//        	if (notifgroup==null) {
//        		notifgroup = new Notif();
//			}
//        	else {
//        		notifgroup.count++;
//        	}
//        	
//			Intent intentmuc = new Intent(MyService.this, Client.class);
//			intentmuc.putExtra("type", "muc");
//			intentmuc.putExtra("userChat", inviter);
//			intentmuc.putExtra("mucId", notifgroup.id);
//			intentmuc.putExtra("roster", false);
//			intentmuc.putExtra("room", room);
//			intentmuc.putExtra("password", password);
////			startActivity(intentmuc);
//			
//			Notification notifmuc = new Notification(R.drawable.icon,
//	        		"Notify", System.currentTimeMillis());
//	        notifmuc.setLatestEventInfo(MyService.this,
//				    getText(R.string.app_name),
//				    notifgroup.count+" new muc",
//				    PendingIntent.getActivity(MyService.this, 0, intentmuc, PendingIntent.FLAG_CANCEL_CURRENT));
//			notificationManager.notify(notifgroup.id, notifmuc);
//			contactnotif.put(inviter, notifgroup);
//			
//			Client.setRoster(false);
//			
//		}
//	};

	private class Notif {
		int id;
		int count;
		public Notif() {
			this.id = (int) (Math.random()*1000);
			this.count = 1;
		}
	}
	
	public static HashMap<String, Notif> messagenotif = new HashMap<String, Notif>();
	public static HashMap<String, Notif> contactnotif = new HashMap<String, Notif>();
	public static HashMap<String, Notif> mucnotif = new HashMap<String, Notif>();
	public static HashMap<String, Notif> groupnotif = new HashMap<String, Notif>();
	
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		System.out.println("service create");
		notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
		
//    	roster.setSubscriptionMode(SubscriptionMode.manual);
    	
    	presenceListener = new PacketListener() {
			@Override
			public void processPacket(Packet packet) {
				// TODO Auto-generated method stub
				System.out.println("subscribe listener");
                System.out.println("dua");
                System.out.println(packet.toXML().toString());
                
                if (packet instanceof Message) {
                	System.out.println("Message!!!");
                	System.out.println(((Message) packet).getType());
                	System.out.println(Message.Type.chat);
					if (((Message) packet).getType() == Message.Type.chat) {
						Message mes = (Message)packet;
						// TODO Auto-generated method stub
						if (mes.getBody() != null) {
							String from = StringUtils.parseBareAddress(mes.getFrom().toString());
							Koneksi.getFrom().add(StringUtils.parseName(mes.getFrom()));
							Koneksi.getTo().add(StringUtils.parseName(mes.getTo()));
							Koneksi.getMess().add(StringUtils.parseName(mes.getFrom())+": "+mes.getBody());
							System.out.println("body= "+mes.getBody()+"||from= "+mes.getFrom());
							
							Notif notifobj = messagenotif.get(from);
							if (notifobj == null) {
								notifobj = new Notif();
							}
							else {
								notifobj.count++;
							}
							System.out.println("id "+notifobj.id);
							System.out.println("count "+notifobj.count);
//							int chatId = (int) (Math.random()*1000);
							Intent intentChat = new Intent(MyService.this, Client.class);
							intentChat.putExtra("userChat",from);
							intentChat.putExtra("chatId", notifobj.id);
							intentChat.putExtra("roster", true);
							
							Notification notifChat = new Notification(R.drawable.icon,
					        		"Notify", System.currentTimeMillis());
					        notifChat.setLatestEventInfo(MyService.this,
								    getText(R.string.app_name),
								    "("+notifobj.count+") new message",
								    PendingIntent.getActivity(MyService.this, 0, intentChat, PendingIntent.FLAG_CANCEL_CURRENT));
							notificationManager.notify(notifobj.id, notifChat);
							System.out.println("    "+from);
							messagenotif.put(from, notifobj);
						}
						System.out.println(Koneksi.getMess());
						System.out.println(Koneksi.getFrom());
						System.out.println(Koneksi.getTo());
					}
					else if (((Message) packet).getType() == Message.Type.groupchat) {
						System.out.println("groupchat= "+packet);
					}
					
//					if (packet.getExtension("http://jabber.org/protocol/muc#user") != null) {
//						System.out.println("muc");
//						System.out.println(packet.getFrom());
//						System.out.println(packet.getExtension("http://jabber.org/protocol/muc#user").getElementName());
//						System.out.println(packet.getExtension("http://jabber.org/protocol/muc#user").toXML());
//						
//					}
				}
                else if(packet instanceof Presence) {
					System.out.println(((Presence) packet).getType());
                    if(((Presence)packet).getType().equals(Presence.Type.subscribe)) {
                    	String presencefrom = (String)packet.getFrom();
                    	Notif notifpresence = contactnotif.get(presencefrom);
                    	if (notifpresence==null) {
							notifpresence = new Notif();
						}
                    	else {
                    		notifpresence.count++;
                    	}
                    	
                    	Intent intentRe = new Intent(MyService.this, Client.class);
						intentRe.putExtra("userChat", presencefrom);
						intentRe.putExtra("presenceId", notifpresence.id);
						intentRe.putExtra("roster", false);
						Notification notifContact = new Notification(R.drawable.icon,
				        		"Notify", System.currentTimeMillis());
						notifContact.setLatestEventInfo(MyService.this,
							    getText(R.string.app_name),
							    notifpresence.count+" new subscribe",
							    PendingIntent.getActivity(MyService.this, 0, intentRe, PendingIntent.FLAG_CANCEL_CURRENT));
						notificationManager.notify(notifpresence.id, notifContact);
						contactnotif.put(presencefrom, notifpresence);
						
						Client.setRoster(false);
                        
//                    	System.out.println("2 "+presencefrom+"||||||||"+((Presence)packet).getTo());
//                    	System.out.println(roster.getEntries());
//                    	System.out.println("3 "+StringUtils.parseName(((Presence)packet).getFrom()));
                    	
                    }
                }
                
			}
		};
		
		connection.addPacketListener(presenceListener, 
				new OrFilter(new PacketTypeFilter(Presence.class), new PacketTypeFilter(Message.class)));
		
		invitationListener = new InvitationListener() {
			
			public void invitationReceived(org.jivesoftware.smack.Connection conn, final String room, 
					final String inviter, String reason, final String password, Message message) {
				// TODO Auto-generated method stub
				System.out.println("conn= "+conn+" ||room= "+room+" ||inviter= "+inviter+" || reason= "+reason+" ||password= "+password+" ||message= "+message);
				
				System.out.println("*****runn********");
				System.out.println("message= "+message.toXML());
				
				org.me.MultiUserChat.room.add(room);
				
            	Notif notifgroup = mucnotif.get(inviter);
            	if (notifgroup==null) {
            		notifgroup = new Notif();
				}
            	else {
            		notifgroup.count++;
            	}
            	
				Intent intentmuc = new Intent(getApplicationContext(), Client.class);
				intentmuc.putExtra("type", "muc");
				intentmuc.putExtra("userChat", inviter);
				intentmuc.putExtra("mucId", notifgroup.id);
				intentmuc.putExtra("roster", false);
				intentmuc.putExtra("room", room);
				intentmuc.putExtra("password", password);
//				startActivity(intentmuc);
				
				Notification notifmuc = new Notification(R.drawable.icon,
		        		"Notify", System.currentTimeMillis());
		        notifmuc.setLatestEventInfo(MyService.this,
					    getText(R.string.app_name),
					    notifgroup.count+" new muc",
					    PendingIntent.getActivity(MyService.this, 0, intentmuc, PendingIntent.FLAG_CANCEL_CURRENT));
				notificationManager.notify(notifgroup.id, notifmuc);
				mucnotif.put(inviter, notifgroup);
				
				Client.setRoster(false);
			}
		};
		
		try {
			MultiUserChat.addInvitationListener(connection, invitationListener);
			errorMUC = false;
		} catch (NullPointerException e) {
			// TODO: handle exception
			errorMUC = true;
		}
		
//		MultiUserChat.addInvitationListener(connection, new InvitationListener() {
//			@Override
//			public void invitationReceived(XMPPConnection conn, final String room, 
//					final String inviter, String reason, final String password, Message message) {
//				// TODO Auto-generated method stub
//				System.out.println("conn= "+conn+" ||room= "+room+" ||inviter= "+inviter+" || reason= "+reason+" ||password= "+password+" ||message= "+message);
//				
//				System.out.println("*****runn********");
//				System.out.println("message= "+message.toXML());
//				
//				org.me.MultiUserChat.room.add(room);
//				
//            	Notif notifgroup = mucnotif.get(inviter);
//            	if (notifgroup==null) {
//            		notifgroup = new Notif();
//				}
//            	else {
//            		notifgroup.count++;
//            	}
//            	
//				Intent intentmuc = new Intent(MyService.this, Client.class);
//				intentmuc.putExtra("type", "muc");
//				intentmuc.putExtra("userChat", inviter);
//				intentmuc.putExtra("mucId", notifgroup.id);
//				intentmuc.putExtra("roster", false);
//				intentmuc.putExtra("room", room);
//				intentmuc.putExtra("password", password);
////				startActivity(intentmuc);
//				
//				Notification notifmuc = new Notification(R.drawable.icon,
//		        		"Notify", System.currentTimeMillis());
//		        notifmuc.setLatestEventInfo(MyService.this,
//					    getText(R.string.app_name),
//					    notifgroup.count+" new muc",
//					    PendingIntent.getActivity(MyService.this, 0, intentmuc, PendingIntent.FLAG_CANCEL_CURRENT));
//				notificationManager.notify(notifgroup.id, notifmuc);
//				contactnotif.put(inviter, notifgroup);
//				
//				Client.setRoster(false);
//				
////				MultiUserChat mMultiUserChat = new MultiUserChat(connection, room);
////				try {
////					if (password != null) {
////						mMultiUserChat
////							.join(StringUtils.parseName(Koneksi.getInstance().getConnection().getUser()),
////									password);
////					} else {
////						mMultiUserChat
////							.join(StringUtils.parseName(Koneksi.getInstance().getConnection().getUser()));
////					}
////				} catch (XMPPException e) {
////				}
//			}
//		});
		
	}
	
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
//		connection.removePacketListener(presenceListener);
		System.out.println(errorMUC);
		if (!errorMUC) {
			MultiUserChat.removeInvitationListener(connection, invitationListener);
		}
		System.out.println("service stop");
	}

	@Override
	public void onStart(Intent intent, int startId) {
		// TODO Auto-generated method stub
		super.onStart(intent, startId);
//		Intent service = new Intent(this, MyService.class);
//		ServiceConnection serviceconn = new ServiceConnection() {
//			
//			@Override
//			public void onServiceDisconnected(ComponentName name) {
//				// TODO Auto-generated method stub
//				
//			}
//			
//			@Override
//			public void onServiceConnected(ComponentName name, IBinder service) {
//				// TODO Auto-generated method stub
//				
//			}
//		};
//		bindService(service, serviceconn, BIND_AUTO_CREATE);
//		startService(service);
		System.out.println("service start");
	}

}
